/*
 * Copyright (c) 2019-2020, https://api.iot.10086.cn/(https://gitee.com/cmcc-iot-api/iot-card-open-application/).
 */
package cn.iot.card.open.ec.service;

import cn.iot.card.open.constants.Constants;
import cn.iot.card.open.constants.ErrorCode;
import cn.iot.card.open.constants.UrlConstants;
import cn.iot.card.open.ec.dto.*;
import cn.iot.card.open.modular.entity.Account;
import cn.iot.card.open.modular.model.BlocDto;
import cn.iot.card.open.modular.model.ResultDTO;
import cn.iot.card.open.modular.service.AccountService;
import cn.iot.card.open.modular.token.TokenService;
import cn.iot.card.open.pojo.page.LayuiPageFactory;
import cn.iot.card.open.pojo.page.LayuiPageInfo;
import cn.iot.card.open.util.ApiRequestUtil;
import cn.iot.card.open.util.CommonUtil;
import cn.iot.card.open.util.JsonUtil;
import cn.stylefeng.roses.core.util.ToolUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fasterxml.jackson.core.type.TypeReference;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.*;


/**
 * 集团综合信息业务操作
 *
 * @author 何光鑫
 * @date 20200108 17:29:12
 * @modify 20200108 何光鑫 v1.0 创建
 * @since v1.0
 */
@Service
@Slf4j
public class EcBlocSynService {

    /**
     * 是否是最后一页
     */
    private static final String LASTPAGEFLAG = "N";

    /**
     * 上一次的页码
     */
    private long prePage = 1;

    /**
     * 上一次的总数
     */
    private long preTotal = 0;

    /**
     * 上一次的页条数
     */
    private long preSize = 0;

    @Autowired
    private ApiRequestUtil apiRequestUtil;

    @Autowired
    private TokenService tokenService;

    @Autowired
    private AccountService accountService;

    /**
     * 调用api接口 查找集团综合信息
     *
     * @param transId
     * @param accountId 集团id
     * @return 返回
     * @author 何光鑫
     * @date 20200109 15:42:15
     * @modify 20200109 何光鑫 v1.0 创建
     * @since v1.0
     */
    public LayuiPageInfo selectBlocByAccountId(String transId,Long accountId) throws IOException{
        if (ToolUtil.isEmpty(accountId)) {
            log.info("[{}] get Bloc error, accountId is null.", transId);
            return LayuiPageFactory.createEmptyPageInfo();
        }
        BlocDto blocDto = new BlocDto();
        Account account = accountService.getById(accountId);
        blocDto.setAccountId(accountId);
        blocDto.setBlocName(account.getBlocName());
        blocDto.setEcId(account.getEcId());
        //查询当前账号的卡号总数
        String totalNum = queryBlocTotalNum(transId,String.valueOf(accountId));

        blocDto.setTotalCards(totalNum);
        List<BlocDto> list = new ArrayList<>();
        list.add(blocDto);
        LayuiPageInfo result = new LayuiPageInfo();
        result.setCount(list.size());
        result.setData(list);
        return result;
    }

    /**
     * 调用API接口查询指定集团用户数（总卡数）
     *
     * @param transId
     * @param accountId 集团id
     * @throws IOException
     * @author 何光鑫
     * @date 20200108 17:29:12
     * @modify 20200108 何光鑫 v1.0 创建
     * @since v1.0
     */
    private String queryBlocTotalNum(String transId, String accountId) throws IOException {
        String totalNum = "";
        Map<String, String> parameterMap = new HashMap<>();
        // 得到queryDate截至日期，默认昨天
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(Constants.SIMPLE_DATE_FORMAT);
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.DATE,-1);
        String queryDate = simpleDateFormat.format(calendar.getTime());
        // 封装请求参数
        parameterMap.put(Constants.REQUEST_QUERY_DATE,queryDate);
        String url = UrlConstants.QUERY_BLOC_TOTAL_NUM;
        // 调用api接口：先获取token，然后带着token调用api接口
        ResultDTO tokenResultDTO = doRequest(true, accountId, transId, parameterMap,url);
        // 如果此处响应失败即为获取token失败，返回失败原因
        if (!tokenResultDTO.getCode().equals(ErrorCode.SUCCESS.getCode())) {
            ErrorCode errorCode = ErrorCode.getByCode(tokenResultDTO.getCode());
            log.warn("[{}] query blocTotalNum token error first,error message is {}.",transId, errorCode.getMsg());
            return errorCode.getMsg();
        }
        // 获取token成功后解析api接口的响应结果
        String responseStr = tokenResultDTO.getMsg();
        String code = CommonUtil.getApiRspCode(responseStr);
        // 获取api接口的响应结果状态码，如果状态码为12021（token不存在或已过期），则重新获取token后再次调用api接口
        if (ErrorCode.ERR12021.getCode().equals(code)) {
            log.warn("[{}] token[accountId:{}] of query blocTotalNum is invalid and start to get a new token.", transId, accountId);
            tokenResultDTO = doRequest(false, accountId, transId, parameterMap,url);
            // 如果此处响应失败即为获取token失败，返回失败原因
            if (!tokenResultDTO.getCode().equals(ErrorCode.SUCCESS.getCode())) {
                ErrorCode errorCode = ErrorCode.getByCode(tokenResultDTO.getCode());
                log.warn("[{}] query blocTotalNum token error second,error message is {}.", transId, errorCode.getMsg());
                return errorCode.getMsg();
            }
            responseStr = tokenResultDTO.getMsg();
        }
        log.info("[{}] query blocTotalNum result string is {}.", transId, responseStr);
        // 组装页面信息
        Map<String,Object> result = JsonUtil.parseJson(responseStr, new TypeReference<Map<String,Object>>() {});
        code = (String)result.get(Constants.RESPONSE_STATUS);
        if (!ErrorCode.SUCCESS.getCode().equals(code)) {
            // 请求失败
            log.warn("[{}] query blocTotalNum error,error message is {}.", transId, result.get(Constants.RESPONSE_MESSAGE));
            return result.get(Constants.RESPONSE_MESSAGE).toString();
        }
        List<Map<String,String>> list;
        list = (List) result.get(Constants.RESPONSE_RESULT);

        if(ToolUtil.isNotEmpty(list)) {
            Map<String,String> map = list.get(0);
            //判断返回值是否为null
            String responseTotalNum = map.get(Constants.RESPONSE_TOTAL_NUM);
            if(ToolUtil.isNotEmpty(responseTotalNum)){
                totalNum = map.get(Constants.RESPONSE_TOTAL_NUM);
            }else{
                log.warn("[{}] query blocTotalNum end,the data of result is null.", transId);
            }
        } else {
            log.warn("[{}] query blocTotalNum end,result is null.", transId);
        }
        return totalNum;
    }

    /**
     * 调用API接口查询集团短信白名单
     *
     * @param transId
     * @param accountId 集团id
     * @param msisdn 卡号
     * @return 返回 page
     * @throws IOException
     * @author 何光鑫
     * @date 20200110 09:31:18
     * @modify 20200110 何光鑫 v1.0 创建
     * @since v1.0
     */
    public LayuiPageInfo queryWhiteList(String transId, String accountId,String msisdn) throws IOException {
        Map<String, String> parameterMap = new HashMap<>();
        Page page = LayuiPageFactory.defaultPage();
        String startNum = String.valueOf(page.getCurrent());
        String pageSize = String.valueOf(page.getSize());
        parameterMap.put(Constants.REQUEST_PARAM_STARTNUM, startNum);
        parameterMap.put(Constants.REQUEST_PARAM_PAGESIZE, pageSize);
        String url = UrlConstants.QUERY_BLOC_WHITE_LIST;
        ResultDTO tokenResultDTO = doRequest(true, accountId, transId, parameterMap,url);
        if (!tokenResultDTO.getCode().equals(ErrorCode.SUCCESS.getCode())) {
            ErrorCode errorCode = ErrorCode.getByCode(tokenResultDTO.getCode());
            log.warn("[{}] query whiteList token error first,error message is {}.",transId, errorCode);
            return LayuiPageFactory.cteateErrorMsg(errorCode);
        }
        String responseStr = tokenResultDTO.getMsg();
        String code = CommonUtil.getApiRspCode(responseStr);
        // 获取状态码，状态码为12021，TOKEN超出规定使用时限或错误
        if (ErrorCode.ERR12021.getCode().equals(code)) {
            log.warn("[{}] token[accountId:{}] is invalid and start to get a new token.", transId, accountId);
            tokenResultDTO = doRequest(false, accountId, transId, parameterMap,url);
            if (!tokenResultDTO.getCode().equals(ErrorCode.SUCCESS.getCode())) {
                ErrorCode errorCode = ErrorCode.getByCode(tokenResultDTO.getCode());
                log.warn("[{}] query whiteList token error second,error message is {}.",transId, errorCode);
                return LayuiPageFactory.cteateErrorMsg(errorCode);
            }
        }
        responseStr = tokenResultDTO.getMsg();
        log.info("[{}] query result string is {}.", transId, responseStr);
        // 组装页面信息
        ResponseDto<BlocWhiteListDTO> result = JsonUtil.parseJson(responseStr, new TypeReference<ResponseDto<BlocWhiteListDTO>>() {});
        code = result.getStatus();
        if (!ErrorCode.SUCCESS.getCode().equals(code)) {
            // 请求失败
            log.warn("[{}] query whiteList error,error message is {}.", transId, result.getMessage());
            return LayuiPageFactory.cteateErrorMsg(ErrorCode.getByCode(code));
        }
        List<BlocWhiteListDTO> whiteLists = result.getResult();
        if (ToolUtil.isEmpty(whiteLists)) {
            log.warn("[{}] query whiteList end,result is null.", transId);
            return LayuiPageFactory.createEmptyPageInfo();
        }
        BlocWhiteListDTO blocWhiteListDTO = whiteLists.get(0);
        List<BlocWhiteListCardDTO> blocWhiteListCardDTOList = blocWhiteListDTO.getCardList();
        // 如果传了卡号msisdn，在集团物联卡里查找
        List<BlocWhiteListCardDTO> selectList = new ArrayList<>();
        if(ToolUtil.isNotEmpty(msisdn)){
            for(BlocWhiteListCardDTO blocWhiteListCardDTO : blocWhiteListCardDTOList){
                if(msisdn.equals(blocWhiteListCardDTO.getMsisdn())){
                    selectList.add(blocWhiteListCardDTO);
                    break;
                }
            }
        } else {
            selectList = blocWhiteListCardDTOList;
        }
        // 后一页
        if (page.getCurrent() > prePage) {
            if (LASTPAGEFLAG.equals(blocWhiteListDTO.getFlag())) {
                // 如果不是最后一页，设置总数超过当前数，点亮下一页按钮
                preTotal = preSize * page.getCurrent();
                page.setTotal(preTotal + 1);
            } else {
                preTotal = selectList.size() + preSize * prePage;
                page.setTotal(preTotal);
            }
        } else if (page.getCurrent() == 1){
            // 第一页
            preSize = selectList.size();
            if (LASTPAGEFLAG.equals(blocWhiteListDTO.getFlag())) {
                // 如果不是最后一页，设置总数超过当前数，点亮下一页按钮
                page.setTotal(preSize + 1);
            } else {
                page.setTotal(preSize);
            }
            preTotal = preSize;
        } else {
            // 前一页
            page.setTotal(preTotal);
        }
        prePage = page.getCurrent();
        preSize = selectList.size();
        page.setRecords(selectList);
        return LayuiPageFactory.createPageInfo(page);
    }

    /**
     * 调用 API 接口查询集团已订购资费
     *
     * @param transId
     * @param accountId 集团id
     * @return 返回 list
     * @throws IOException
     * @author 何光鑫
     * @date 20200110 09:31:18
     * @modify 20200110 何光鑫 v1.0 创建
     * @since v1.0
     */
    public LayuiPageInfo queryOrderCharges(String transId, String accountId,Map<String, String> parameterMap) throws IOException {
        String url = UrlConstants.QUERY_BLOC_ORDER_CHARGES;
        // 调用api接口：先获取token，然后带着token调用api接口
        ResultDTO tokenResultDTO = doRequest(true, accountId, transId, parameterMap,url);
        // 如果此处响应失败即为获取token失败，返回失败原因
        if (!tokenResultDTO.getCode().equals(ErrorCode.SUCCESS.getCode())) {
            ErrorCode errorCode = ErrorCode.getByCode(tokenResultDTO.getCode());
            log.warn("[{}] query orderCharges token error first,error message is {}.",transId, errorCode);
            return LayuiPageFactory.cteateErrorMsg(errorCode);
        }
        // 获取token成功后解析api接口的响应结果
        String responseStr = tokenResultDTO.getMsg();
        String code = CommonUtil.getApiRspCode(responseStr);
        // 获取api接口的响应结果状态码，如果状态码为12021（token不存在或已过期），则重新获取token后再次调用api接口
        if (ErrorCode.ERR12021.getCode().equals(code)) {
            log.warn("[{}] token[accountId:{}] is invalid and start to get a new token.", transId, accountId);
            tokenResultDTO = doRequest(false, accountId, transId, parameterMap,url);
            // 如果此处响应失败即为获取token失败，返回失败原因
            if (!tokenResultDTO.getCode().equals(ErrorCode.SUCCESS.getCode())) {
                ErrorCode errorCode = ErrorCode.getByCode(tokenResultDTO.getCode());
                log.warn("[{}] query orderCharges token error second,error message is {}.",transId, errorCode);
                return LayuiPageFactory.cteateErrorMsg(errorCode);
            }
            // 获取token成功后，重置responseStr（api接口的响应结果）
            responseStr = tokenResultDTO.getMsg();
        }
        log.info("[{}] query result string is {}.", transId, responseStr);
        // 组装页面信息
        ResponseDto<BlocOrderChargesListDTO> result = JsonUtil.parseJson(responseStr, new TypeReference<ResponseDto<BlocOrderChargesListDTO>>() {});
        code = result.getStatus();
        if (!ErrorCode.SUCCESS.getCode().equals(code)) {
            // 如果api接口返回失败，则返回失败原因
            log.warn("[{}] query orderCharges error,error message is {}.", transId, result.getMessage());
            return LayuiPageFactory.cteateErrorMsg(ErrorCode.getByCode(code));
        }
        List<BlocOrderChargesListDTO> orderChargesList = result.getResult();
        if (ToolUtil.isEmpty(orderChargesList)) {
            log.warn("[{}] query orderCharges end,result is null.", transId);
        }
        List<BlocOrderChargesDTO> blocOrderChargesDTOList = orderChargesList.get(0).getOfferingInfoList();
        Page page = LayuiPageFactory.defaultPage();
        page.setTotal(blocOrderChargesDTOList.size());
        page.setRecords(blocOrderChargesDTOList);
        return LayuiPageFactory.createPageInfo(page);
    }

    /**
     * 调用 API 接口查询集团物联卡生命周期分布
     *
     * @param transId
     * @param accountId 集团id
     * @return 返回 map
     * @throws IOException
     * @author 何光鑫
     * @date 20200113 15:09:37
     * @modify 20200113 何光鑫 v1.0 创建
     * @since v1.0
     */
    public Map<String,Object> queryStatusNumber(String transId, String accountId) throws IOException {
        if (StringUtils.isBlank(accountId)) {
            log.info("[{}] query statusNumber accountId is null.", transId);
            return null;
        }
        Map<String,Object> errorMap = new HashMap<>();
        Map<String, String> parameterMap = new HashMap<>();
        String url = UrlConstants.QUERY_BLOC_STATUS_NUMBER;
        ResultDTO tokenResultDTO = doRequest(true, accountId, transId, parameterMap,url);
        if (!tokenResultDTO.getCode().equals(ErrorCode.SUCCESS.getCode())) {
            ErrorCode errorCode = ErrorCode.getByCode(tokenResultDTO.getCode());
            log.warn("[{}] query statusNumber token error first,error message is {}.", transId, errorCode);
            errorMap.put(Constants.RESPONSE_ERROR,errorCode.getMsg());
            return errorMap;
        }
        String responseStr = tokenResultDTO.getMsg();
        if (StringUtils.isEmpty(responseStr)) {
            // 请求失败
            log.warn("[{}] query statusNumber error,response is null.", transId);
            return null;
        }
        String code = CommonUtil.getApiRspCode(responseStr);
        // 获取状态码，状态码为12021，TOKEN超出规定使用时限或错误
        if (ErrorCode.ERR12021.getCode().equals(code)) {
            log.warn("[{}] token[accountId:{}] is invalid and start to get a new token.", transId, accountId);
            tokenResultDTO = doRequest(false, accountId, transId, parameterMap,url);
            if (!tokenResultDTO.getCode().equals(ErrorCode.SUCCESS.getCode())) {
                ErrorCode errorCode = ErrorCode.getByCode(tokenResultDTO.getCode());
                log.warn("[{}] query statusNumber token error second,error message is {}.", transId, errorCode);
                errorMap.put(Constants.RESPONSE_ERROR,errorCode.getMsg());
                return errorMap;
            }
        }
        responseStr = tokenResultDTO.getMsg();
        log.info("[{}] query result string is {}.", transId, responseStr);
        // 组装页面信息
        ResponseDto<BlocStatusNumberDTO> result = JsonUtil.parseJson(responseStr, new TypeReference<ResponseDto<BlocStatusNumberDTO>>() {});
        code = result.getStatus();
        if (!ErrorCode.SUCCESS.getCode().equals(code)) {
            // 请求失败
            log.warn("[{}] query statusNumber error,error message is {}.", transId, result.getMessage());
            errorMap.put(Constants.RESPONSE_ERROR, result.getMessage());
            return errorMap;
        }
        BlocStatusNumberDTO blocStatusNumberDTO = result.getResult().get(0);
        if (ToolUtil.isEmpty(blocStatusNumberDTO)) {
            log.warn("[{}] query statusNumber end,result is null.", transId);
        }
        String blocStatusNumberDTOStr = JsonUtil.toJson(blocStatusNumberDTO);
        Map<String,Object> blocStatusNumberDTOMaps = JsonUtil.parseJson(blocStatusNumberDTOStr, new TypeReference<Map<String,Object>>(){});
        if(ToolUtil.isEmpty(blocStatusNumberDTOMaps.get(Constants.STATUS_NUMBER_TEST))){
            blocStatusNumberDTOMaps.put(Constants.STATUS_NUMBER_TEST,0);
        }
        if(ToolUtil.isEmpty(blocStatusNumberDTOMaps.get(Constants.STATUS_NUMBER_READY))){
            blocStatusNumberDTOMaps.put(Constants.STATUS_NUMBER_READY,0);
        }
        if(ToolUtil.isEmpty(blocStatusNumberDTOMaps.get(Constants.STATUS_NUMBER_INACT))){
            blocStatusNumberDTOMaps.put(Constants.STATUS_NUMBER_INACT,0);
        }
        if(ToolUtil.isEmpty(blocStatusNumberDTOMaps.get(Constants.STATUS_NUMBER_ACT))){
            blocStatusNumberDTOMaps.put(Constants.STATUS_NUMBER_ACT,0);
        }
        if(ToolUtil.isEmpty(blocStatusNumberDTOMaps.get(Constants.STATUS_NUMBER_SUSPEND))){
            blocStatusNumberDTOMaps.put(Constants.STATUS_NUMBER_SUSPEND,0);
        }
        if(ToolUtil.isEmpty(blocStatusNumberDTOMaps.get(Constants.STATUS_NUMBER_PRETER))){
            blocStatusNumberDTOMaps.put(Constants.STATUS_NUMBER_PRETER,0);
        }
        return blocStatusNumberDTOMaps;
    }

    /**
     * 调用 API 接口查询集团总账单（月）
     *
     * @param transId
     * @param accountId 集团id
     * @param queryDate 查询日期
     * @return 返回 map
     * @throws IOException
     * @author 何光鑫
     * @date 20200110 15:53:02
     * @modify 20200110 何光鑫 v1.0 创建
     * @since v1.0
     */
    public Map<String,Object> queryEcBill(String transId, String accountId,String queryDate) throws IOException {
        if (StringUtils.isBlank(accountId)) {
            log.info("[{}] query ecBill error, accountId is null.", transId);
            return null;
        }
        Map<String, String> parameterMap = new HashMap<>();
        Map<String,Object> resultMap = new HashMap<>();
        Double invoiceAmount = 0D;
        Double openAmount = 0D;
        resultMap.put(Constants.EC_BILL_INVOICE_AMOUNT,invoiceAmount);
        resultMap.put(Constants.EC_BILL_OPEN_AMOUNT,openAmount);
        resultMap.put(Constants.REQUEST_QUERY_DATE,queryDate);
        resultMap.put(Constants.RESPONSE_ECHARTS_STATUS,Constants.RESPONSE_ECHARTS_RIGHT);
        parameterMap.put(Constants.REQUEST_QUERY_DATE,queryDate);
        String url = UrlConstants.QUERY_EC_BILL;
        ResultDTO tokenResultDTO = doRequest(true, accountId, transId, parameterMap,url);
        if (!tokenResultDTO.getCode().equals(ErrorCode.SUCCESS.getCode())) {
            ErrorCode errorCode = ErrorCode.getByCode(tokenResultDTO.getCode());
            log.warn("[{}] query ecBill token error first,error message is {}.",transId, errorCode);
            resultMap.put(Constants.RESPONSE_ERROR,errorCode.getMsg());
            return resultMap;
        }
        String responseStr = tokenResultDTO.getMsg();
        if (StringUtils.isEmpty(responseStr)) {
            // 请求失败
            log.warn("[{}] query ecBill error,response is null.", transId);
            return null;
        }

        String code = CommonUtil.getApiRspCode(responseStr);
        // 获取状态码，状态码为12021，TOKEN超出规定使用时限或错误
        if (ErrorCode.ERR12021.getCode().equals(code)) {
            log.warn("[{}] token[accountId:{}] is invalid and start to get a new token.", transId, accountId);
            tokenResultDTO = doRequest(false, accountId, transId, parameterMap,url);
            if (!tokenResultDTO.getCode().equals(ErrorCode.SUCCESS.getCode())) {
                ErrorCode errorCode = ErrorCode.getByCode(tokenResultDTO.getCode());
                log.warn("[{}] query ecBill token error second,error message is {}.",transId, errorCode);
                resultMap.put(Constants.RESPONSE_ERROR,errorCode.getMsg());
                return resultMap;
            }
        }
        responseStr = tokenResultDTO.getMsg();
        log.info("[{}] query result string is {}.", transId, responseStr);
        // 组装页面信息
        ResponseDto<EcBillListDTO> result = JsonUtil.parseJson(responseStr, new TypeReference<ResponseDto<EcBillListDTO>>() {});
        code = result.getStatus();
        if (!ErrorCode.SUCCESS.getCode().equals(code)) {
            // 请求失败
            log.warn("[{}] query ecBill error,error message is {}.", transId, result.getMessage());
            resultMap.put(Constants.RESPONSE_ERROR,result.getMessage());
            resultMap.put(Constants.RESPONSE_ECHARTS_STATUS,Constants.RESPONSE_ECHARTS_ERROR);
            return resultMap;
        }
        List<EcBillListDTO> ecBillListDTO = result.getResult();
        if (ToolUtil.isEmpty(ecBillListDTO)) {
            log.warn("[{}] query ecBill end,result is null.", transId);
        }
        List<EcBillDTO> ecBillDTOList = ecBillListDTO.get(0).getBillingList();
        String ecBillDTOListStr = JsonUtil.toJson(ecBillDTOList);
        List<Map<String,Object>> ecBillDTOListMaps = JsonUtil.parseJson(ecBillDTOListStr, new TypeReference<List<Map<String,Object>>>(){});

        //封装参数，算总账单
        if(ToolUtil.isNotEmpty(ecBillDTOListMaps)){
            for(int i = 0;i< ecBillDTOListMaps.size();i++){
                invoiceAmount += Double.valueOf((String)ecBillDTOListMaps.get(i).get(Constants.EC_BILL_INVOICE_AMOUNT));
                openAmount += Double.valueOf((String)ecBillDTOListMaps.get(i).get(Constants.EC_BILL_OPEN_AMOUNT));
            }
        }
        resultMap.put(Constants.EC_BILL_INVOICE_AMOUNT,invoiceAmount);
        resultMap.put(Constants.EC_BILL_OPEN_AMOUNT,openAmount);
        resultMap.put(Constants.REQUEST_QUERY_DATE,queryDate);

        return resultMap;
    }

    /**
     * 调用API接口查询物联卡风险等级分布（按月查询）
     *
     * @param transId
     * @param accountId 集团id
     * @param queryDate 查询日期
     * @return 返回 map
     * @throws IOException
     * @author 何光鑫
     * @date 20200113 09:07:10
     * @modify 20200113 何光鑫 v1.0 创建
     * @since v1.0
     */
    public Map<String,Object> queryRiskLevel(String transId, String accountId,String queryDate) throws IOException {
        if (StringUtils.isBlank(accountId)) {
            log.info("[{}] query riskLevel accountId is null.", transId);
            return null;
        }
        Map<String,Object> errorMap = new HashMap<>();
        Map<String, String> parameterMap = new HashMap<>();
        parameterMap.put(Constants.REQUEST_QUERY_DATE,queryDate);
        String url = UrlConstants.QUERY_RISK_LEVEL_MONTHLY;
        ResultDTO tokenResultDTO = doRequest(true, accountId, transId, parameterMap,url);
        if (!tokenResultDTO.getCode().equals(ErrorCode.SUCCESS.getCode())) {
            ErrorCode errorCode = ErrorCode.getByCode(tokenResultDTO.getCode());
            log.warn("[{}] query riskLevel token error first,error message is {}.",transId, errorCode);
            errorMap.put(Constants.RESPONSE_ERROR,errorCode.getMsg());
            return errorMap;
        }
        String responseStr = tokenResultDTO.getMsg();
        if (StringUtils.isEmpty(responseStr)) {
            // 请求失败
            log.warn("[{}] query riskLevel error,response is null.", transId);
            return null;
        }
        String code = CommonUtil.getApiRspCode(responseStr);
        // 获取状态码，状态码为12021，TOKEN超出规定使用时限或错误
        if (ErrorCode.ERR12021.getCode().equals(code)) {
            log.warn("[{}] token[accountId:{}] is invalid and start to get a new token.", transId, accountId);
            tokenResultDTO = doRequest(false, accountId, transId, parameterMap,url);
            if (!tokenResultDTO.getCode().equals(ErrorCode.SUCCESS.getCode())) {
                ErrorCode errorCode = ErrorCode.getByCode(tokenResultDTO.getCode());
                log.warn("[{}] query riskLevel token error second,error message is {}.",transId, errorCode);
                errorMap.put(Constants.RESPONSE_ERROR,errorCode.getMsg());
                return errorMap;
            }
        }
        responseStr = tokenResultDTO.getMsg();
        log.info("[{}] query result string is {}.", transId, responseStr);
        // 组装页面信息
        ResponseDto<BlocRiskLevelDTO> result = JsonUtil.parseJson(responseStr, new TypeReference<ResponseDto<BlocRiskLevelDTO>>() {});
        code = result.getStatus();
        if (!ErrorCode.SUCCESS.getCode().equals(code)) {
            // 请求失败
            log.warn("[{}] query riskLevel error,error message is {}.", transId, result.getMessage());
            errorMap.put(Constants.RESPONSE_ERROR,result.getMessage());
            return errorMap;
        }
        List<BlocRiskLevelDTO> blocRiskLevelDTOS = result.getResult();
        if (ToolUtil.isEmpty(blocRiskLevelDTOS)) {
            log.warn("[{}] query riskLevel end,result is null." ,transId);
        }
        //计算各风险等级个数
        Long risk001 = 0L;
        Long risk002 = 0L;
        Long risk003 = 0L;
        Long risk004 = 0L;
        for(BlocRiskLevelDTO blocRiskLevelDTO:blocRiskLevelDTOS){
            if(blocRiskLevelDTO.getRiskLevel().equals(Constants.BLOC_RISK_001)){
                risk001 += Long.valueOf(blocRiskLevelDTO.getRiskNum());
            }else if(blocRiskLevelDTO.getRiskLevel().equals(Constants.BLOC_RISK_002)){
                risk002 += Long.valueOf(blocRiskLevelDTO.getRiskNum());
            }else if(blocRiskLevelDTO.getRiskLevel().equals(Constants.BLOC_RISK_003)){
                risk003 += Long.valueOf(blocRiskLevelDTO.getRiskNum());
            }else{
                risk004 += Long.valueOf(blocRiskLevelDTO.getRiskNum());
            }
        }

        //封装参数，算总账单
        Map<String,Object> resultMap = new HashMap<>();
        resultMap.put(Constants.BLOC_RISK_001,risk001);
        resultMap.put(Constants.BLOC_RISK_002,risk002);
        resultMap.put(Constants.BLOC_RISK_003,risk003);
        resultMap.put(Constants.BLOC_RISK_004,risk004);
        return resultMap;
    }

    /**
     * 高风险物联卡类型分布查询
     *
     * @param transId
     * @param accountId
     * @param queryDate
     * @return 返回 map
     * @throws IOException
     * @author 何光鑫
     * @date 20200113 15:03:39
     * @modify 20200113 何光鑫 v1.0 创建
     * @since v1.0
     */
    public Map<String,Object> queryHighRisk(String transId, String accountId,String queryDate) throws IOException {
        if (StringUtils.isBlank(accountId)) {
            log.info("[{}] query highRisk accountId is null.", transId);
            return null;
        }
        Map<String,Object> errorMap = new HashMap<>();
        Map<String, String> parameterMap = new HashMap<>();
        parameterMap.put(Constants.REQUEST_QUERY_DATE,queryDate);
        String url = UrlConstants.QUERY_HIGH_RISK_MONTHLY;
        ResultDTO tokenResultDTO = doRequest(true, accountId, transId, parameterMap,url);
        if (!tokenResultDTO.getCode().equals(ErrorCode.SUCCESS.getCode())) {
            ErrorCode errorCode = ErrorCode.getByCode(tokenResultDTO.getCode());
            log.warn("[{}] query highRisk token error first,error message is {}.",transId, errorCode);
            errorMap.put(Constants.RESPONSE_ERROR,errorCode.getMsg());
            return errorMap;
        }
        String responseStr = tokenResultDTO.getMsg();
        if (StringUtils.isEmpty(responseStr)) {
            // 请求失败
            log.warn("[{}] query highRisk error,response is null.", transId);
            return null;
        }
        String code = CommonUtil.getApiRspCode(responseStr);
        // 获取状态码，状态码为12021，TOKEN超出规定使用时限或错误
        if (ErrorCode.ERR12021.getCode().equals(code)) {
            log.warn("[{}] token[accountId:{}] is invalid and start to get a new token.", transId, accountId);
            tokenResultDTO = doRequest(false, accountId, transId, parameterMap,url);
            if (!tokenResultDTO.getCode().equals(ErrorCode.SUCCESS.getCode())) {
                ErrorCode errorCode = ErrorCode.getByCode(tokenResultDTO.getCode());
                log.warn("[{}] query highRisk token error second,error message is {}.",transId, errorCode);
                errorMap.put(Constants.RESPONSE_ERROR,errorCode.getMsg());
                return errorMap;
            }
        }
        responseStr = tokenResultDTO.getMsg();
        log.info("[{}] query result string is {}.", transId, responseStr);
        // 组装页面信息
        ResponseDto<BlocHighRiskDTO> result = JsonUtil.parseJson(responseStr, new TypeReference<ResponseDto<BlocHighRiskDTO>>() {});
        code = result.getStatus();
        if (!ErrorCode.SUCCESS.getCode().equals(code)) {
            // 请求失败
            log.warn("[{}] query highRisk error,error message is {}.", transId, result.getMessage());
            errorMap.put(Constants.RESPONSE_ERROR,result.getMessage());
            return errorMap;
        }
        List<BlocHighRiskDTO> blocHighRiskDTOS = result.getResult();
        if (ToolUtil.isEmpty(blocHighRiskDTOS)) {
            log.warn("[{}] query highRisk end,result is null.", transId);
        }
        //计算各风险等级个数
        Long risk001001 = 0L;
        Long risk001002 = 0L;
        Long risk001003 = 0L;
        for(BlocHighRiskDTO blocHighRiskDTO:blocHighRiskDTOS){
            if(blocHighRiskDTO.getRiskType().equals(Constants.BLOC_RISK_001001)){
                risk001001 += Long.valueOf(blocHighRiskDTO.getRiskNum());
            }else if(blocHighRiskDTO.getRiskType().equals(Constants.BLOC_RISK_001002)){
                risk001002 += Long.valueOf(blocHighRiskDTO.getRiskNum());
            }else{
                risk001003 += Long.valueOf(blocHighRiskDTO.getRiskNum());
            }
        }

        //封装参数，算总账单
        Map<String,Object> resultMap = new HashMap<>();
        resultMap.put(Constants.BLOC_RISK_001001,risk001001);
        resultMap.put(Constants.BLOC_RISK_001002,risk001002);
        resultMap.put(Constants.BLOC_RISK_001003,risk001003);
        return resultMap;
    }


    /**
     * 封装调用API接口的请求参数
     *
     * @param tokenValid true表示使用已经初始化了的token值，false表示使用重新生成的token值
     * @param accountId 集团id
     * @param transId
     * @param parameterMap  调用API接口的请求参数
     * @param url 调用API接口的请求路径
     * @return 返回 调用API接口的返回结果字符串
     * @throws IOException
     * @author 何光鑫
     * @date 20200108 17:29:12
     * @modify 20200108 何光鑫 v1.0 创建
     * @since v1.0
     */
    private ResultDTO doRequest(boolean tokenValid, String accountId, String transId, Map<String, String> parameterMap,String url) throws IOException {
        // 根据 accountId 查询 token
        ResultDTO tokenResultDTO = tokenService.getToken(tokenValid, accountId);
        if (!tokenResultDTO.getCode().equals(ErrorCode.SUCCESS.getCode())) {
            return tokenResultDTO;
        }
        parameterMap.put(Constants.REQUEST_PARAM_TOKEN, tokenResultDTO.getMsg());
        parameterMap.put(Constants.REQUEST_PARAM_TRANSID, transId);
        String methodUrl = apiRequestUtil.buildRequestUrl(parameterMap, url);
        log.info("[{}] request url is {}.", transId, methodUrl);
        tokenResultDTO.setMsg(apiRequestUtil.doGet(methodUrl));
        return tokenResultDTO;
    }
}
